//
//  SenseArMaterialService.h
//  SenseArMaterial
//
//  Created by sluin on 16/10/9.
//  Copyright © 2016年 SenseTime. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "SenseArClient.h"
#import "SenseArMaterial.h"
#import "SenseArCptMaterial.h"
#import "SenseArMaterialGroup.h"
#import "SenseArMaterialHistoryInfo.h"
#import "SenseArFrameActionInfo.h"

/**
 服务器类型
 */
typedef enum : NSUInteger {
    
    /**
     国内正式服务器
     */
    DomesticServer,
  
    /**
     国际正式服务器
     */
    InternationalServer
    
} SenseArServerType;

/**
 客户端类型配置状态
 */
typedef enum : NSUInteger {
    
    /**
     配置成功
     */
    CONFIG_OK = 0,
    
    /**
     配置的类型不容许
     */
    CONFIG_CLIENT_NOT_ALLOWED,
    
    /**
     无效TOKEN
     */
    TOKEN_INVALID,
    
    /**
     不可知状态
     */
    CONFIG_CLIENT_UNKNOWN,
    
} SenseArConfigStatus;

/**
 鉴权错误码
 */
typedef enum : NSUInteger {
    
    /**
     无效 AppID/SDKKey
     */
    AUTHORIZE_ERROR_KEY_NOT_MATCHED = 1,
    
    /**
     网络不可用
     */
    AUTHORIZE_ERROR_NETWORK_NOT_AVAILABLE,
    
    /**
     未知错误
     */
    AUTHORIZE_ERROR_UNKNOWN,
    
} SenseArAuthorizeError;



/**
 下载状态码
 */
typedef enum : NSUInteger {
    
    /**
     下载成功
     */
    Success = 0,
    
    /**
     网络未连接
     */
    NetworkUnavailable,
    
    /**
     Group 未发现
     */
    GroupNotFound,
    
    /**
     下载未许可
     */
    NotAuthorized,
    
    /**
     未知错误
     */
    UnknownError
    
} SenseArDownloadStatus;


/*
 最大缓存值 , 不启用 LRU 淘汰规则 .
 */
FOUNDATION_EXTERN const int SENSEAR_CACHE_SIZE_MAX;

@interface SenseArMaterialService : NSObject

/**
 获取 Material 服务
 
 @return 合作商对应的 Material 服务
 */
+ (SenseArMaterialService *)sharedInstance;


/**
 释放资源
 */
+ (void)releaseResources;


/**
 *  SenseAr SDK 使用 license 文件路径生成激活码.生成的激活码需要自行保存,以待下次验证.如果 license 更新需要重新生成激活码.
 *
 *  @param strLicensePath license 文件路径
 *  @param error          生成激活码时产生的错误
 *
 *  @return 生成的激活码
 */
+ (NSString *)generateActiveCodeWithLicensePath:(NSString *)strLicensePath
                                          error:(NSError **)error;

/**
 *  SenseAr SDK 使用 license 文件内容生成激活码.生成的激活码需要自行保存,以待下次验证.如果 license 更新需要重新生成激活码.
 *
 *  @param dataLicense license 文件二进制内容
 *  @param error       生成激活码时产生的错误
 *
 *  @return 生成的激活码
 */
+ (NSString *)generateActiveCodeWithLicenseData:(NSData *)dataLicense
                                          error:(NSError **)error;

/**
 *  SenseAr SDK 使用 license 文件路径验证激活码
 *
 *  @param strActiveCode  激活码
 *  @param strLicensePath license 文件路径
 *  @param error          验证激活码时产生的错误
 *
 *  @return 是否通过 , YES为通过检查.
 */
+ (BOOL)checkActiveCode:(NSString *)strActiveCode
            licensePath:(NSString *)strLicensePath
                  error:(NSError **)error;

/**
 *  SenseAr SDK 使用 license 文件内容验证激活码
 *
 *  @param strActiveCode 激活码
 *  @param dataLicense   license 文件二进制内容
 *  @param error         验证激活码时产生的错误
 *
 *  @return 是否通过 , YES为通过检查.
 */
+ (BOOL)checkActiveCode:(NSString *)strActiveCode licenseData:(NSData *)dataLicense
                  error:(NSError **)error;


/**
 远程授权,未授权的 service 不可用
 
 @param strAppID        注册的合作商 ID
 @param strAppKey       注册的合作商 key
 @param completeSuccess 注册成功后的回调
 @param completeFailure 注册失败后的回调 , iErrorCode : 错误码
 */
- (void)authorizeWithAppID:(NSString *)strAppID
                    appKey:(NSString *)strAppKey
                 onSuccess:(void (^)(void))completeSuccess
                 onFailure:(void (^)(SenseArAuthorizeError iErrorCode))completeFailure;

/**
 服务是否授权
 
 @return YES : 已授权 , NO : 未授权
 */
+ (BOOL)isAuthorized;


/**
 配置使用服务的客户端 , 未经配置的 SenseArMaterialService 不可使用
 
 @param iClientType 配置的客户端类型
 @param client      配置的客户端
 
 @return 配置客户状态
 */
- (SenseArConfigStatus)configureClientWithType:(SenseArClientType)iClientType
                                        client:(SenseArClient *)client;




/**
 预加载Material列表
 
 @param strUserID 用户ID
 */
- (void)preDownloadWithUserID:(NSString *)strUserID;


/**
 获取分组列表
 
 @param completeSuccess 获取分组列表成功 , arrMaterialGroups 分组列表 .
 @param completeFailure 获取分组列表失败 , iErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)fetchAllGroupsOnSuccess:(void (^)(NSArray <SenseArMaterialGroup *>* arrMaterialGroups))completeSuccess
                      onFailure:(void (^)(int iErrorCode , NSString *strMessage))completeFailure;

/**
 获取 Material 列表
 
 @param strUserID       用户ID , 如 主播ID, 粉丝ID 等 .
 @param strGroupID      素材所在组的 groupID
 @param completeSuccess 获取素材列表成功 , arrMaterias 素材列表 .
 @param completeFailure 获取素材列表失败 , iErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)fetchMaterialsWithUserID:(NSString *)strUserID
                         GroupID:(NSString *)strGroupID
                       onSuccess:(void (^)(NSArray <SenseArMaterial *>* arrMaterials))completeSuccess
                       onFailure:(void (^)(int iErrorCode , NSString *strMessage))completeFailure;


/**
 获取 Material 列表
 
 @param strUserID       用户ID , 如 主播ID, 粉丝ID 等 .
 @param strGroupID      素材所在组的 groupID
 @param adMode          素材类型
 @param completeSuccess 获取素材列表成功 , arrMaterias 素材列表 .
 @param completeFailure 获取素材列表失败 , iErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)fetchMaterialsWithUserID:(NSString *)strUserID
                         GroupID:(NSString *)strGroupID
                          adMode:(SenseArMaterialType)adMode
                       onSuccess:(void (^)(NSArray <SenseArMaterial *>* arrMaterials))completeSuccess
                       onFailure:(void (^)(int iErrorCode , NSString *strMessage))completeFailure;




/**
 通过 userID , materialID 获取单个素材
 
 @param strUserID 用户标识
 @param strMaterialID 素材标识
 @param completeSuccess 获取素材成功 , material 获取的素材 .
 @param completeFailure 获取失败 , iErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)fetchMaterialWithUserID:(NSString *)strUserID
                     materialID:(NSString *)strMaterialID
                      onSuccess:(void (^)(SenseArMaterial *material))completeSuccess
                      onFailure:(void (^)(int iErrorCode , NSString *strMessage))completeFailure;


/**
 获取 CPT Material 列表
 
 @param strUserID       用户ID , 如 主播ID, 粉丝ID 等 , 该参数必填 .
 @param completeSuccess 获取素材列表成功 , arrMaterias 素材列表 .
 @param completeFailure 获取素材列表失败 , iErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)fetchCptMaterialsWithUserID:(NSString *)strUserID
                          onSuccess:(void (^)(NSArray <SenseArCptMaterial *>* arrCptMaterials))completeSuccess
                          onFailure:(void (^)(int iErrorCode , NSString *strMessage))completeFailure;


/**
 获取完成广告的历史记录

 @param strUserID 用户ID , 如 主播ID, 粉丝ID 等 , 该参数必填 .
 @param iCurrentPage 页码
 @param iPageSize 每页广告个数
 @param completeSuccess 获取成功 , iCurrentPage 页码, iPageSize 每页广告个数 , iTotalCount 总个数 , fTotalAmount 总金额, arrMaterialInfo 成功获取的历史信息
 @param completeFailure 获取失败 , iCurrentPage 页码, iPageSize 每页广告个数 , ErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)fetchHistoryMaterialsWithUserID:(NSString *)strUserID
                            currentPage:(int)iCurrentPage
                               pageSize:(int)iPageSize
                              onSuccess:(void (^)(int iCurrentPage ,
                                                  int iPageSize ,
                                                  int iTotalCount ,
                                                  float fTotalAmount ,
                                                  NSArray <SenseArMaterialHistoryInfo *>* arrMaterialInfo))completeSuccess

                              onFailure:(void (^)(int iCurrentPage ,
                                                  int iPageSize ,
                                                  int iErrorCode ,
                                                  NSString *strMessage))completeFailure;

/**
 抢广告

 @param strMaterialID CPT广告素材ID
 @param strUserID 用户ID , 如 主播ID, 粉丝ID 等 , 该参数必填 .
 @param completeSuccess strMaterialID CPT广告素材ID , iGrabResult 广告抢单结果 , strGrabRsultDescribtion 广告抢单结果描述 , iRemainingStock 广告库存
 @param completeFailure strMaterialID CPT广告素材ID , iErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)grabCptMaterialWithMaterialID:(NSString *)strMaterialID
                    userID:(NSString *)strUserID
                 onSuccess:(void (^)(NSString *strMaterialID ,
                                     SenseArCptGrabResult iGrabResult ,
                                     NSString *strGrabRsultDescribtion ,
                                     int iRemainingStock))completeSuccess
                 onFailure:(void (^)(NSString *strMaterialID,
                                     int iErrorCode ,
                                     NSString *strMessage))completeFailure;

/**
 检查素材是否有效
 
 @param strMaterialID 要检查的素材ID
 @param strUserID 用户ID , 如 主播ID, 粉丝ID 等 , 该参数必填 .
 @param completeSuccess 检查请求成功 , strMaterialID 所检查素材ID , iAdStatus 所检查素材状态 , 所检查素材状态描述
 @param completeFailure 检查请求失败 , strMaterialID 所检查素材ID , iErrorCode 错误码 , strMessage 错误描述 .
 */
- (void)checkWithMaterialID:(NSString *)strMaterialID
                     userID:(NSString *)strUserID
                  onSuccess:(void (^)(NSString *strMaterialID ,
                                      SenseArAdStatus iAdStatus ,
                                      NSString *strAdStatusDescribtion))completeSuccess
                  onFailure:(void (^)(NSString *strMaterialID ,
                                      int iErrorCode ,
                                      NSString *strMessage))completeFailure;

/**
 能否合法绘制
 
 @return YES : 可以绘制 , NO : 不可以绘制
 */
+ (BOOL)isAuthorizedForRender;


/**
 素材是否已下载
 
 @param material 需要判断是否已下载的素材
 
 @return YES 已下载 , NO 未下载或下载中 .
 */
- (BOOL)isMaterialDownloaded:(SenseArMaterial *)material;


/**
 下载素材
 
 @param material        下载的素材
 @param completeSuccess 下载成功 , material 下载的素材
 @param completeFailure 下载失败 , material 下载的素材 , iErrorCode 错误码 , strMessage 错误描述
 @param processingCallBack 下载中 , material 下载的素材 , fProgress 下载进度 , iSize 已下载大小
 */
- (void)downloadMaterial:(SenseArMaterial *)material
               onSuccess:(void (^)(SenseArMaterial *material))completeSuccess
               onFailure:(void (^)(SenseArMaterial *material , int iErrorCode , NSString *strMessage))completeFailure
              onProgress:(void (^)(SenseArMaterial *material , float fProgress , int64_t iSize))processingCallBack;

/**
 素材任务取消
 
 @param material 取消下载的素材
 @param resultCallBack 任务取消回调 , material 取消下载的素材 , iErrorCode 错误码 , strMessage 错误描述
 */
- (void)cancelDownloadingMaterial:(SenseArMaterial *)material
                         onResult:(void (^)(SenseArMaterial *material, int iErrorCode, NSString *strMessage))resultCallBack;

/**
 设置素材缓存大小 , 默认 100M 超过限制会遵循LRU淘汰规则删除已有素材包 . 如果不需要设置最大缓存可以设置为 SENSEAR_CACHE_SIZE_MAX 来禁用 LRU 淘汰规则 .
 
 @param iSize 缓存大小 (Byte)
 */
- (void)setMaxCacheSize:(int64_t)iSize;

/**
 获取素材缓存所占用的空间
 
 @return 素材缓存所占用的空间 (单位:Byte)
 */
- (int64_t)getMaterialCacheSize;

/**
 清除缓存 , 清除内存缓存和素材磁盘缓存 , 但是会保留必要的数据库文件等 .
 */
- (void)clearCache;


/**
 获取 SDK 版本号
 
 @return SDK 版本号
 */
+ (NSString *)getSdkVersion;


/**
 根据配置生成预加载的素材
 
 @param  strJson 配置JSON
 @return 预加载的素材列表
 */
- (NSArray <SenseArMaterial *>* )genPrebuiltMaterialsByConfiguration:(NSString*)strJson;

/**
 删除单个素材缓存

 @param  material 要删除缓存的素材
 @return 是否成功 YES：成功 NO：失败
 */
- (BOOL)clearCacheWithMaterial:(SenseArMaterial *)material;



/**
 切换服务器 , 需要先于其他网络接口调用

 @param iServerType 服务器类型
 */
+ (void)switchToServerType:(SenseArServerType)iServerType;


@end
